package control;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.font.ShapeGraphicAttribute;
import java.io.IOException;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import mode.Shape;
import mode.ShapeFactory;
import mode.ShapeListener;
import mode.Wall;
import view.GamePn;
import view.ScorePn;

public class TetrisMain extends JFrame implements ActionListener, ShapeListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private GamePn gamePn;
	private ScorePn scorePn;
	private Shape shape, nextShape;
	private Wall wall;
	private JMenuBar mb;
	private String[][] menuItem = { { "New Game", "Start", "Pause" },
			{ "Level 1", "Level 2", "Level 3", "Level 4", "Level 5" }, { "About", "Game Help" } };
	private JMenuItem startItem;
	private JMenuItem pauseItem;
	private JMenuItem newItem;
	private int keepspeed = 0;

	public TetrisMain() throws ClassNotFoundException, IOException {
		// TODO Auto-generated constructor stub
		setTitle("俄罗斯方块");
		setSize(420, 560);
		setLayout(null);
		setResizable(false);
		Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
		Dimension framesize = this.getSize();
		int x = (int) screensize.getWidth() / 2 - (int) framesize.getWidth() / 2;
		int y = (int) screensize.getHeight() / 2 - (int) framesize.getHeight() / 2;
		setLocation(x, y);
		setVisible(true);

		String[] menu = { "GAME", "LEVEL", "HELP" };
		mb = new JMenuBar();
		for (int i = 0; i < menu.length; i++) {
			JMenu jm = new JMenu(menu[i]);
			mb.add(jm);
			for (int j = 0; j < menuItem[i].length; j++) {
				if (i == 0 && j == 1) {
					startItem = new JMenuItem(menuItem[0][1]);
					startItem.addActionListener(this);
					startItem.setEnabled(false);
					jm.add(startItem);
				} else if (i == 0 && j == 2) {
					pauseItem = new JMenuItem(menuItem[0][2]);
					pauseItem.addActionListener(this);
					jm.add(pauseItem);
				} else if (i == 0 && j == 0) {
					newItem = new JMenuItem(menuItem[0][0]);
					newItem.addActionListener(this);
					jm.add(newItem);
				} else {
					JMenuItem jmi = new JMenuItem(menuItem[i][j]);
					jmi.addActionListener(this);
					jm.add(jmi);
				}
			}
		}
		setJMenuBar(mb);

		shape = ShapeFactory.createShape();
		wall = new Wall();
		gamePn = new GamePn(wall);
		gamePn.setLocation(5, 5);
		add(gamePn);
		shape.addObserver(gamePn);

		scorePn = new ScorePn();
		scorePn.setLocation(305, 5);
		add(scorePn);

		addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				// TODO Auto-generated method stub
				super.keyPressed(e);
				int code = e.getKeyCode();

				switch (code) {
				case KeyEvent.VK_LEFT:
					if (wall.isAllowMove(shape, Shape.LEFT))
						shape.moveLeft();
					break;
				case KeyEvent.VK_RIGHT:
					if (wall.isAllowMove(shape, Shape.RIGHT))
						shape.moveRight();
					break;
				case KeyEvent.VK_UP:
					if (wall.isAllowMove(shape, Shape.UPROTATE))
						shape.rotate();
					break;
				case KeyEvent.VK_DOWN:
					if (wall.isAllowMove(shape, Shape.DOWN))
						shape.moveDown();
				default:
					break;
				}
			}
		});

		startGame();
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					new TetrisMain();
				} catch (ClassNotFoundException | IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}

	public void startGame() throws ClassNotFoundException, IOException {
		shape.openShapeThread(this);
		nextShape = ShapeFactory.createShape();
		scorePn.display(nextShape);
	}

	@Override
	public synchronized boolean isAllowMoveLister() {
		// TODO Auto-generated method stub
		if (wall.isAllowMove(shape, Shape.DOWN)) {
			keepspeed = shape.getSpeed();
			return true;
		}
		int s = wall.save(shape);
		shape = nextShape;
		shape.addObserver(gamePn);
		shape.setSpeed(keepspeed);
		if (!shape.isStop())
			shape.openShapeThread(this);
		if (!wall.getTop()) {
			try {
				nextShape = ShapeFactory.createShape();
			} catch (ClassNotFoundException | IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			scorePn.display(nextShape);
		}
		scorePn.showScore(s);
		return false;
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		String com = e.getActionCommand();

		switch (com) {
		case "New Game":
			if (wall.isNew()) {
				shape.setStop(false);
				wall.init();
				scorePn.init();
				try {
					startGame();
				} catch (ClassNotFoundException | IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				shape.setSpeed(500);
				startItem.setEnabled(false);
				wall.setNew(false);
			}
			break;
		case "Start":
			shape.setStop(false);
			wall.setTop(false);
			shape.openShapeThread(this);
			startItem.setEnabled(false);
			pauseItem.setEnabled(true);
			break;
		case "Pause":
			shape.setStop(true);
			pauseItem.setEnabled(false);
			startItem.setEnabled(true);
			break;
		case "Level 1":
			shape.setSpeed(100);
			scorePn.showLevel("1");
			break;
		case "Level 2":
			shape.setSpeed(300);
			scorePn.showLevel("2");
			break;
		case "Level 3":
			shape.setSpeed(500);
			scorePn.showLevel("3");
			break;
		case "Level 4":
			shape.setSpeed(700);
			scorePn.showLevel("4");
			break;
		case "Level 5":
			shape.setSpeed(900);
			scorePn.showLevel("5");
			break;
		case "About":
			JOptionPane.showMessageDialog(this, "Author :   xiang xin\nVersion :    1.0\nEmail :    542345948@qq.com");
			break;
		case "Game Help":
			JOptionPane.showMessageDialog(this,
					"游戏规则：\n通过LEVEL菜单栏选择等级；\n按左右键改变方块向左或右移动；\n按向上键改变方块的形状；\n按向下键加快方块下移速度；\n");
			break;
		default:
			break;
		}
	}
}
